package org.tinygroup.tinytest.contextloader;

import java.util.ArrayList;

import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.BeanDefinitionReader;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.context.support.GenericApplicationContext;
import org.tinygroup.beancontainer.BeanContainerFactory;
import org.tinygroup.springutil.ExtendsSpringBeanContainer;
import org.tinygroup.tinyrunner.Runner;

/**
 * 
 * @author renhui
 *
 */
public class TinyGenericXmlContextLoader extends AbstractGenericContextLoader {

	/**
	 * Create a new {@link XmlBeanDefinitionReader}.
	 * 
	 * @return a new XmlBeanDefinitionReader.
	 * @see XmlBeanDefinitionReader
	 */
	@Override
	protected BeanDefinitionReader createBeanDefinitionReader(
			final GenericApplicationContext context) {
		return new XmlBeanDefinitionReader(context);
	}

	/**
	 * Returns &quot;<code>-context.xml</code>&quot;.
	 */
	@Override
	public String getResourceSuffix() {
		return "-context.xml";
	}

	@Override
	protected void prepareContext(GenericApplicationContext context) {
		// 启动tiny框架
		FileSystemXmlApplicationContext applicationContext = new FileSystemXmlApplicationContext();
		BeanContainerFactory.initBeanContainer(ExtendsSpringBeanContainer.class
				.getName());
		ExtendsSpringBeanContainer beanContainer = (ExtendsSpringBeanContainer) BeanContainerFactory
				.getBeanContainer(getClass().getClassLoader());
		beanContainer.setApplicationContext(applicationContext);
		Runner.init(ExtendsSpringBeanContainer.class, null,
				new ArrayList<String>());
		context.setParent(applicationContext);
	}

	@Override
	protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
		ExtendsSpringBeanContainer beanContainer = (ExtendsSpringBeanContainer) BeanContainerFactory
				.getBeanContainer(getClass().getClassLoader());
		ApplicationContext parentContext = beanContainer
				.getBeanContainerPrototype();
		DefaultListableBeanFactory parentListableBeanFactory = (DefaultListableBeanFactory) parentContext
				.getAutowireCapableBeanFactory();
		for (BeanPostProcessor beanPostProcessor : parentListableBeanFactory
				.getBeanPostProcessors()) {
			beanFactory.addBeanPostProcessor(beanPostProcessor);
		}
	}

	protected void postRefresh(GenericApplicationContext context) {
		ExtendsSpringBeanContainer beanContainer = (ExtendsSpringBeanContainer) BeanContainerFactory
				.getBeanContainer(getClass().getClassLoader());
		ApplicationContext parentContext = beanContainer
				.getBeanContainerPrototype();
		AbstractApplicationContext applicationContext = (AbstractApplicationContext) parentContext;
		for (BeanFactoryPostProcessor beanFactoryPostProcessor : applicationContext
				.getBeanFactoryPostProcessors()) {
			context.addBeanFactoryPostProcessor(beanFactoryPostProcessor);
		}
		String[] postProcessorNames = applicationContext.getBeanNamesForType(
				BeanFactoryPostProcessor.class, true, false);
		for (String ppName : postProcessorNames) {
			context.addBeanFactoryPostProcessor(applicationContext.getBean(
					ppName, BeanFactoryPostProcessor.class));
		}
		DefaultListableBeanFactory parentListableBeanFactory = (DefaultListableBeanFactory) parentContext
				.getAutowireCapableBeanFactory();
		for (BeanPostProcessor beanPostProcessor : parentListableBeanFactory
				.getBeanPostProcessors()) {
			context.getDefaultListableBeanFactory().addBeanPostProcessor(
					beanPostProcessor);
		}
	}

}